24 #define foreach(x, v) for (typeof (v).begin() x=(v).begin(); x !=(v).end(); ++x)
25 #define For(i, a, b) for (int i=(a); i<(b); ++i)
26 #define D(x) cout << #x " is " << x << endl
30 typedef pair
<int, int> point
;
31 typedef vector
< point
> polygon
;
33 vector
< polygon
> polygons
;
39 return p
[u
] == u
? u
: p
[u
] = find(p
[u
]);
42 void link(int u
, int v
) {
43 if (find(u
) != find(v
)) {
49 // Returns an angle in the range [0, 2*Pi) of a given Cartesian point.
50 // If the point is (0,0), -1.0 is returned.
53 // define EPS 0.000000001, or your choice
54 // P has members x and y.
55 double polarAngle( point p
) {
56 double x
= p
.first
, y
= p
.second
;
57 if(fabs(x
) <= EPS
&& fabs(y
) <= EPS
) return -1.0;
58 if(fabs(x
) <= EPS
) return (y
> EPS
? 1.0 : 3.0) * acos(0);
59 double theta
= atan(1.0 * y
/ x
);
60 if(x
> EPS
) return(y
>= -EPS
? theta
: (4*acos(0) + theta
));
61 return(2 * acos( 0 ) + theta
);
64 //Point inside polygon
65 // Returns true iff p is inside poly.
66 // PRE: The vertices of poly are ordered (either clockwise or
68 // POST: Modify code inside to handle the special case of "on
74 // define EPS 0.000000001, or your choice
75 bool pointInPoly( point p
, const polygon
&poly
) {
78 for(int i
= n
- 1, j
= 0; j
< n
; i
= j
++){
79 point
v( poly
[i
].first
- p
.first
, poly
[i
].second
- p
.second
);
80 point
w( poly
[j
].first
- p
.first
, poly
[j
].second
- p
.second
);
81 double va
= polarAngle(v
);
82 double wa
= polarAngle(w
);
84 if(va
< -0.5 || wa
< -0.5 || fabs(fabs(xx
)-2*acos(0)) < EPS
){
85 // POINT IS ON THE EDGE
91 if( xx
< -2 * acos( 0 ) ) ang
+= xx
+ 4 * acos( 0 );
92 else if( xx
> 2 * acos( 0 ) ) ang
+= xx
- 4 * acos( 0 );
95 return( ang
* ang
> 1.0 );
100 Returns true if point (x, y) lies inside (or in the border)
101 of box defined by points (x0, y0) and (x1, y1).
103 bool point_in_box(double x
, double y
,
104 double x0
, double y0
,
105 double x1
, double y1
){
107 min(x0
, x1
) <= x
&& x
<= max(x0
, x1
) &&
108 min(y0
, y1
) <= y
&& y
<= max(y0
, y1
);
113 Finds the intersection between two segments (Not infinite
115 Segment 1 goes from point (x0, y0) to (x1, y1).
116 Segment 2 goes from point (x2, y2) to (x3, y3).
118 (Can be modified to find the intersection between a segment
121 Handles the case when the 2 segments are:
122 *Parallel but don't lie on the same line (No intersection)
123 *Parallel and both lie on the same line (Infinite
124 *intersections or no intersections)
125 *Not parallel (One intersection or no intersections)
127 Returns true if the segments do intersect in any case.
129 bool segment_segment_intersection(int x1
, int y1
,
135 int d1
= (x1
- x3
) * (y4
- y3
) - (y1
- y3
) * (x4
- x3
);
136 int d2
= (x2
- x3
) * (y4
- y3
) - (y2
- y3
) * (x4
- x3
);
137 int d3
= (x3
- x1
) * (y2
- y1
) - (y3
- y1
) * (x2
- x1
);
138 int d4
= (x4
- x1
) * (y2
- y1
) - (y4
- y1
) * (x2
- x1
);
140 bool b1
= d1
> 0 and d2
< 0 or d1
< 0 and d2
> 0;
141 bool b2
= d3
> 0 and d4
< 0 or d3
< 0 and d4
> 0;
142 if (b1
and b2
) return true;
143 if (d1
== 0 and point_in_box(x1
, y1
, x3
, y3
, x4
, y4
)) return true;
144 if (d2
== 0 and point_in_box(x2
, y2
, x3
, y3
, x4
, y4
)) return true;
145 if (d3
== 0 and point_in_box(x3
, y3
, x1
, y1
, x2
, y2
)) return true;
146 if (d4
== 0 and point_in_box(x4
, y4
, x1
, y1
, x2
, y2
)) return true;
150 bool polygonsIntersect(const polygon
&a
, const polygon
&b
) {
151 int na
= a
.size(), nb
= b
.size();
152 for (int i
= 0; i
< na
; ++i
) {
153 if (pointInPoly(a
[i
], b
)) return true;
155 for (int i
= 0; i
< nb
; ++i
) {
156 if (pointInPoly(b
[i
], a
)) return true;
159 for (int i
= 0; i
< na
; ++i
) {
160 for (int j
= 0; j
< nb
; ++j
) {
161 int xa1
= a
[i
].first
, ya1
= a
[i
].second
;
162 int xa2
= a
[(i
+ 1) % na
].first
, ya2
= a
[(i
+ 1) % na
].second
;
163 int xb1
= b
[j
].first
, yb1
= b
[j
].second
;
164 int xb2
= b
[(j
+ 1) % nb
].first
, yb2
= b
[(j
+ 1) % nb
].second
;
165 if (segment_segment_intersection(xa1
, ya1
, xa2
, ya2
, xb1
, yb1
, xb2
, yb2
)) {
177 int n
= polygons
.size();
178 for (int i
= 0; i
< n
; ++i
) {
182 for (int i
= 0; i
< n
; ++i
) {
183 for (int j
= i
+ 1; j
< n
; ++j
) {
184 if (polygonsIntersect(polygons
[i
], polygons
[j
])) {
190 for (int i
= 0; i
< n
; ++i
) {
193 cout
<< ans
.size() << endl
;
201 string s
; getline(cin
, s
);
203 for (int i
= 0; i
< n
; ++i
){
204 polygons
.push_back(polygon());
208 while (sin
>> x
>> y
) {
209 polygons
.back().push_back(point(x
, y
));
211 assert(polygons
.back().size() >= 3);
213 assert(polygons
.size() == n
);